'\" te
.\"  Copyright (c) 2006, Sun Microsystems, Inc., All Rights Reserved
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
.TH MKIOCB 9F "May 21, 2022"
.SH NAME
mkiocb \- allocates a STREAMS ioctl block for M_IOCTL messages in the kernel.
.SH SYNOPSIS
.nf
#include <sys/stream.h>



\fBmblk_t *\fR\fBmkiocb\fR(\fBuint_t\fR \fIcommand\fR);
.fi

.SH INTERFACE LEVEL
illumos DDI specific (illumos DDI).
.SH PARAMETERS
.ne 2
.na
\fB\fIcommand\fR\fR
.ad
.RS 11n
ioctl command for the \fBioc_cmd\fR field.
.RE

.SH DESCRIPTION
STREAMS modules or drivers might need to issue an ioctl to a lower module or
driver. The \fBmkiocb()\fR function tries to allocate (using \fBallocb\fR(9F))
a STREAMS \fBM_IOCTL\fR message block (\fBiocblk\fR(9S)). Buffer allocation
fails only when the system is out of memory. If no buffer is available, the
\fBqbufcall\fR(9F) function can help a module recover from an allocation
failure.
.sp
.LP
The \fBmkiocb\fR function returns a \fBmblk_t\fR structure which is large
enough to hold any of the ioctl messages (\fBiocblk\fR(9S),
.BR copyreq (9S)
or \fBcopyresp\fR(9S)), and has the following special properties:
.sp
.ne 2
.na
\fB\fBb_wptr\fR\fR
.ad
.RS 20n
Set to \fBb_rptr + sizeof(struct iocblk)\fR.
.RE

.sp
.ne 2
.na
\fB\fBb_cont\fR\fR
.ad
.RS 20n
Set to \fINULL\fR.
.RE

.sp
.ne 2
.na
\fB\fBb_datap->db_type\fR\fR
.ad
.RS 20n
Set to \fBM_IOCTL\fR.
.RE

.sp
.LP
The fields in the iocblk structure are initialized as follows:
.sp
.ne 2
.na
\fB\fBioc_cmd\fR\fR
.ad
.RS 13n
Set to the command value passed in.
.RE

.sp
.ne 2
.na
\fB\fBioc_id\fR\fR
.ad
.RS 13n
Set to a unique identifier.
.RE

.sp
.ne 2
.na
\fB\fBioc_cr\fR\fR
.ad
.RS 13n
Set to point to a credential structure encoding the maximum system privilege
and which does not need to be freed in any fashion.
.RE

.sp
.ne 2
.na
\fB\fBioc_count\fR\fR
.ad
.RS 13n
Set to 0.
.RE

.sp
.ne 2
.na
\fB\fBioc_rval\fR\fR
.ad
.RS 13n
Set to 0.
.RE

.sp
.ne 2
.na
\fB\fBioc_error\fR\fR
.ad
.RS 13n
Set to 0.
.RE

.sp
.ne 2
.na
\fB\fBioc_flags\fR\fR
.ad
.RS 13n
Set to \fBIOC_NATIVE\fR to reflect that this is native to the running kernel.
.RE

.SH RETURN VALUES
Upon success, the \fBmkiocb()\fR function returns a pointer to the allocated
\fBmblk_t\fR of type \fBM_IOCTL\fR.
.sp
.LP
On failure, it returns a null pointer.
.SH CONTEXT
The \fBmkiocb()\fR function can be called from user, interrupt, or kernel
context.
.SH EXAMPLES
\fBExample 1 \fR\fBM_IOCTL\fR Allocation
.sp
.LP
The first example shows an \fBM_IOCTL\fR allocation with the ioctl command
\fBTEST_CMD\fR. If the \fBiocblk\fR(9S) cannot be allocated, \fINULL\fR is
returned, indicating an allocation failure (line 5). In line 11, the
\fBputnext\fR(9F) function is used to send the message downstream.

.sp
.in +2
.nf
1  test_function(queue_t *q, test_info_t *testinfo)
 2  {
 3   mblk_t *mp;
 4
 5   if ((mp = mkiocb(TEST_CMD)) == NULL)
 6       return (0);
 7
 8       /* save off ioctl ID value */
 9       testinfo->xx_iocid = ((struct iocblk *)mp->b_rptr)->ioc_id;
10
11       putnext(q, mp);       /* send message downstream */
12       return (1);
13  }
.fi
.in -2

.LP
\fBExample 2 \fRThe ioctl \fBID \fRValue
.sp
.LP
During the read service routine, the ioctl \fBID \fRvalue for \fBM_IOCACK\fR or
\fBM_IOCNAK\fR should equal the ioctl that was previously sent by this module
before processing.

.sp
.in +2
.nf

 1  test_lrsrv(queue_t *q)
 2  {
 3      ...
 4
 5      switch (DB_TYPE(mp)) {
 6      case M_IOCACK:
 7      case M_IOCNAK:
 8          /* Does this match the ioctl that this module sent */
 9          ioc = (struct iocblk*)mp->b_rptr;
10          if (ioc->ioc_id == testinfo->xx_iocid) {
11              /* matches, so process the message */
12              ...
13              freemsg(mp);
14          }
15          break;
16      }
17      ...
18  }
.fi
.in -2

.LP
\fBExample 3 \fRAn iocblk Allocation Which Fails
.sp
.LP
The next example shows an iocblk allocation which fails. Since the open routine
is in user context, the caller may block using \fBqbufcall\fR(9F) until memory
is available.

.sp
.in +2
.nf
1  test_open(queue_t *q, dev_t devp, int oflag, int sflag,
                           cred_t *credp)
 2  {
 3       while ((mp = mkiocb(TEST_IOCTL)) == NULL) {
 4            int id;
 5
 6            id = qbufcall(q, sizeof (union ioctypes), BPRI_HI,
 7                dummy_callback, 0);
 8            /* Handle interrupts */
 9            if (!qwait_sig(q)) {
10                qunbufcall(q, id);
11                return (EINTR);
12            }
13       }
14       putnext(q, mp);
15  }
.fi
.in -2

.SH SEE ALSO
.BR allocb (9F),
.BR putnext (9F),
.BR qbufcall (9F),
.BR qwait_sig (9F),
.BR copyreq (9S),
.BR copyresp (9S),
.BR iocblk (9S)
.sp
.LP
\fIWriting Device Drivers\fR
.sp
.LP
\fISTREAMS Programming Guide\fR
.SH WARNINGS
It is the module's responsibility to remember the \fBID\fR value of the
\fBM_IOCTL\fR that was allocated. This will ensure proper cleanup and \fBID\fR
matching when the \fBM_IOCACK\fR or \fBM_IOCNAK\fR is received.
